package com.apidoc.controller;

import com.apidoc.annotation.ApiOperation;
import com.apidoc.annotation.ApiParam;
import jakarta.annotation.PostConstruct;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 测试控制器：包含各种参数类型和接口场景，用于验证文档生成效果
 */
@RestController
@RequestMapping("/api/test")
public class TestController {

    // 初始化数据（模拟服务启动时加载）

    @PostConstruct
    public void init() {
        System.out.println("TestController 初始化完成");
    }

    /**
     * 1. 基础接口（Query参数 + 路径参数）
     * 测试 @PathVariable 和 @RequestParam 注解
     */
    @ApiOperation(value = "根据用户ID获取用户信息", notes = "支持获取用户详细信息")
    @GetMapping("/user/{userId}")
    public String getUser(
            @PathVariable @ApiParam(value = "用户ID", required = true) Long userId,  // 路径参数
            @RequestParam(required = false, defaultValue = "false")
            @ApiParam(value = "是否返回详细信息", required = false, defaultValue = "false") boolean withDetail// 可选Query参数
    ) {
        return "查询用户ID：" + userId + "，详情：" + withDetail;
    }

    /**
     * 2. 复杂对象参数（@RequestBody）
     * 测试请求体为JSON对象的场景
     */
    @ApiOperation(value = "创建新用户", notes = "通过JSON对象创建用户")
    @PostMapping("/user")
    public UserDTO createUser(@RequestBody @ApiParam(value = "用户信息", required = true) UserDTO user) {
        // 模拟创建用户（返回带ID的对象）
        user.setId(1001L);
        return user;
    }

    /**
     * 3. 表单参数（application/x-www-form-urlencoded）
     * 测试表单提交场景
     */
    @ApiOperation(value = "用户登录", notes = "通过表单提交用户名和密码进行登录")
    @PostMapping(value = "/login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public String login(
            @RequestParam @ApiParam(value = "用户名", required = true) String username,
            @RequestParam @ApiParam(value = "密码", required = true) String password,
            @RequestParam(required = false) @ApiParam(value = "验证码", required = false) String captcha
    ) {
        return "用户 " + username + " 登录成功";
    }

    /**
     * 4. 文件上传接口
     * 测试 MultipartFile 类型参数（无注解时应被识别为文件类型）
     */
    @ApiOperation(value = "文件上传", notes = "支持上传文件和头像")
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String uploadFile(
            @RequestParam("file") @ApiParam(value = "上传文件", required = true) MultipartFile file,  // 带注解的文件参数
            @ApiParam(value = "用户头像", required = false) MultipartFile avatar,  // 无注解的文件参数（应被自动识别）
            @RequestParam @ApiParam(value = "备注信息", required = true) String remark  // 附加文本参数
    ) {
        return "上传文件：" + file.getOriginalFilename() +
                "，头像：" + (avatar != null ? avatar.getOriginalFilename() : "无") +
                "，备注：" + remark;
    }

    /**
     * 5. SSE（Server-Sent Events）接口
     * 测试 SseEmitter 类型参数（无注解时应被识别为SSE类型）
     */
    @ApiOperation(value = "SSE消息推送", notes = "通过SSE推送实时消息")
    @GetMapping("/sse")
    public SseEmitter sseDemo(@ApiParam(value = "SSE连接对象", required = true) SseEmitter emitter) {  // 无注解的SSE参数
        new Thread(() -> {
            try {
                // 模拟推送3条消息
                for (int i = 1; i <= 3; i++) {
                    emitter.send("SSE消息 " + i);
                    TimeUnit.SECONDS.sleep(1);
                }
                emitter.complete();
            } catch (IOException | InterruptedException e) {
                emitter.completeWithError(e);
            }
        }).start();
        return emitter;
    }

    /**
     * 6. 无注解参数接口
     * 测试各种无注解参数的自动识别效果
     */
    @ApiOperation(value = "无注解参数测试", notes = "测试自动识别各种无注解参数")
    @GetMapping("/no-annotation")
    public String noAnnotationParams(
            @ApiParam(value = "用户ID", required = false) Long id,  // 基本类型（应推断为Query参数）
            @ApiParam(value = "用户名称", required = false) String name,  // String类型（应推断为Query参数）
            @ApiParam(value = "标签列表", required = false) List<String> tags,  // 集合类型（应推断为Query多值参数）
            @ApiParam(value = "用户信息", required = false) UserDTO user  // 复杂对象（应推断为Body参数）
    ) {
        return "ID：" + id + "，名称：" + name + "，标签：" + tags + "，用户：" + user;
    }

    /**
     * 7. 数组参数接口
     */
    @ApiOperation(value = "数组参数测试", notes = "测试数组参数处理")
    @GetMapping("/array")
    public String arrayParams(
            @RequestParam @ApiParam(value = "ID数组", required = true) Integer[] ids,  // 数组参数（带注解）
            @ApiParam(value = "名称数组", required = false) String[] names  // 数组参数（无注解）
    ) {
        return "IDs：" + ids.length + "个，Names：" + names.length + "个";
    }

    /**
     * 8. 嵌套对象参数
     */
    @ApiOperation(value = "创建订单", notes = "支持创建包含用户和商品信息的订单")
    @PostMapping("/nested")
    public OrderDTO createOrder(@RequestBody @ApiParam(value = "订单信息", required = true) OrderDTO order) {
        order.setOrderNo("ORD-" + System.currentTimeMillis());
        return order;
    }

    // 内部静态类：用户DTO（用于测试复杂对象）
    public static class UserDTO {
        private Long id;
        private String username;
        private Integer age;
        private String email;

        // Getter和Setter（文档生成需要）
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public Integer getAge() { return age; }
        public void setAge(Integer age) { this.age = age; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }

        @Override
        public String toString() {
            return username + "(" + age + "岁)";
        }
    }

    // 内部静态类：订单DTO（用于测试嵌套对象）
    public static class OrderDTO {
        private String orderNo;
        private UserDTO buyer;  // 嵌套UserDTO
        private List<OrderItemDTO> items;  // 集合嵌套

        // Getter和Setter
        public String getOrderNo() { return orderNo; }
        public void setOrderNo(String orderNo) { this.orderNo = orderNo; }
        public UserDTO getBuyer() { return buyer; }
        public void setBuyer(UserDTO buyer) { this.buyer = buyer; }
        public List<OrderItemDTO> getItems() { return items; }
        public void setItems(List<OrderItemDTO> items) { this.items = items; }
    }

    // 内部静态类：订单项DTO（用于测试多层嵌套）
    public static class OrderItemDTO {
        private String productName;
        private Integer quantity;
        private Double price;

        // Getter和Setter
        public String getProductName() { return productName; }
        public void setProductName(String productName) { this.productName = productName; }
        public Integer getQuantity() { return quantity; }
        public void setQuantity(Integer quantity) { this.quantity = quantity; }
        public Double getPrice() { return price; }
        public void setPrice(Double price) { this.price = price; }
    }
}
